package util.methods;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.channels.ClosedByInterruptException;
import java.io.Writer;

public class ProcessHelpers 
{
    public static int runCommand ( String strCommand ) throws Exception
    {
    	return runCommand ( strCommand, null ); 
    }
    
    public static int runCommand ( String strCommand, Writer outWriter ) throws Exception
    {
        boolean bDone = false;
        Process cap3 = Runtime.getRuntime().exec( strCommand );
        InputStream stdout = cap3.getInputStream();       
        InputStreamReader osr = new InputStreamReader(stdout);
        BufferedReader brOut = new BufferedReader(osr);
        
        InputStream stderr = cap3.getErrorStream();       
        InputStreamReader esr = new InputStreamReader(stderr);
        BufferedReader brErr = new BufferedReader(esr);
        
        int nExitState = Integer.MIN_VALUE;
        
        try
        {
            
            synchronized ( stdout )
            {
            
                
                while ( !bDone )
                {
                    
                    // Send the sub-processes stderr to out stderr
                    while ( brErr.ready() )
                    {
                        System.err.print( (char)brErr.read() );
                    } 
                    
                    // Consume stdout so the process doesn't hang...
                    while ( brOut.ready() )
                    {
                    	int nData = brOut.read();
                    	if ( outWriter != null )
                    		outWriter.write( nData );
                    } 
                    
                    stdout.wait( 3000 /*milliseconds*/ );
                    
                    try
                    {
                        nExitState = cap3.exitValue();
                        bDone = true;
                    }
                    catch ( Exception err )
                    {
                        
                    }
                }
            }
        
            // Send the sub-processes stderr to out stderr
            while ( brErr.ready() )
            {
                System.err.print( (char)brErr.read() );
            } 
        }
        catch ( ClosedByInterruptException ignore )
        {
            
        }
        catch ( InterruptedException ignore )
        {
            
        }
        
        // Kill the process if it's still running.  (Probably the thread was killed by user clicking cancel 
        // and threw one of the above exceptions.)
        if ( !bDone )
            cap3.destroy();          
        if ( outWriter != null )
        	outWriter.flush();
        
        return nExitState;  
    }
    
    private ProcessHelpers () { /* Don't instantiate this */ }
}
